<template>
  <div>
    <Modal v-model="modal.show"  :loading="modal.loading" :title="modal.title"  :mask-closable="false" :footer-hide=true width="1124px" :closable="false">
      <Row>
        <Col span="10">
          <video id="talkVedioEl" ref="talkVedioEl" style="width:100%;height:200px" autoplay controls/>
        </Col>
        <Col span="4">
        </Col>
        <Col span="10">
          <canvas id="waveform" ref="waveform" style="background-color: #ffffff"></canvas>
        </Col>

      </Row>
      <Row>
        <Col span="24">
          <div style="display: flex;justify-content: center">
            <Button @click="close">取消</Button>
          </div>
        </Col>
      </Row>
    </Modal>
  </div>
</template>
<script>
import MediaDevice from "@/api/MediaDevice";
export default {
  data(){
    return{
      modal:{
        show:false,
        loading:false,
        title:"测试麦克风音频"
      },
      playerEl:null,
      MediaStreamTrack:null,

      audioCtx:null,
      sourceNode:null,
      analyser:null,
      //bufferLength:null,// 初始化缓冲区长度
      waveform:null,
      audioWaveTimer:null,

      distortion:null,
      gainNode:null,
      biquadFilter:null,
      convolver:null,
      drawVisual:null,
      max:0
    }
  },
  methods:{
    close(){
      this.modal.show = false;
      if(!!this.playerEl)
      {
        this.playerEl.srcObject = null;
        this.playerEl.load();
      }
      console.log("close: MediaStreamTrack=%o",this.MediaStreamTrack);
      this.MediaStreamTrack && this.MediaStreamTrack.stop();

      if (!!this.audioCtx){
        this.audioCtx.close();
      }

      if (!!this.audioWaveTimer){
        clearInterval(this.audioWaveTimer)
        this.audioWaveTimer=null;
      }
    },
    openDialog() {
      new MediaDevice().getDevices((res)=>{
        console.log(res);
      })

      const _this = this;
      this.modal.show = true;
      console.log("openDialog");
      const constraints = { audio: true, video: { width: 1280, height: 720 } };
      //const constraints = { audio: true };
      navigator.mediaDevices.getUserMedia(constraints)
        .then(function(mediaStream) {
          //console.log(mediaStream)
          _this.playerEl.srcObject = mediaStream;
          //关闭 MIC使用
          _this.MediaStreamTrack=typeof mediaStream.stop==='function'?mediaStream:mediaStream.getTracks()[0];

          //onloadedmetadata 事件
          //_this.playerEl.onloadedmetadata = function(e) {
          //  _this.MediaStreamTrack=typeof mediaStream.stop==='function'?mediaStream:mediaStream.getTracks()[0];
           // _this.playerEl.play();

/*            const audio = document.getElementById('music');
            audio.load();
            audio.play();*/

/*            const ctx = new AudioContext();
            //const audioSrc = ctx.createMediaElementSource(_this.playerEl);
            const audioSrc = ctx.createMediaStreamSource(_this.playerEl.srcObject);
            const analyser = ctx.createAnalyser();

            audioSrc.connect(analyser);
            analyser.connect(ctx.destination);

            analyser.fftSize = 256;
            const bufferLength = analyser.frequencyBinCount;
            const frequencyData = new Uint8Array(bufferLength);

            _this.audioWaveTimer=setInterval(() => {
              analyser.getByteFrequencyData(frequencyData);
              console.log(frequencyData);
            }, 1000);*/
         // };

          /*
          _this.sourceNode = _this.audioCtx.createMediaStreamSource(mediaStream);
          console.log("stream=%o",mediaStream);
          _this.sourceNode.connect(_this.distortion);
          console.log("distortion=%o",_this.distortion);
          _this.distortion.connect(_this.biquadFilter);
          _this.biquadFilter.connect(_this.gainNode);
          _this.convolver.connect(_this.gainNode);
          //_this.echoDelay.placeBetween(_this.gainNode, _this.analyser);
          _this.analyser.connect(_this.audioCtx.destination);

          _this.distortion.oversample = "4x";
          _this.biquadFilter.gain.setTargetAtTime(0, _this.audioCtx.currentTime, 0);
          _this.biquadFilter.disconnect(0);
          _this.biquadFilter.connect(_this.gainNode);
          _this.biquadFilter.type = "lowshelf";
          _this.biquadFilter.frequency.setTargetAtTime(1000, _this.audioCtx.currentTime, 0);
          _this.biquadFilter.gain.setTargetAtTime(25, _this.audioCtx.currentTime, 0);

          //画曲线
          _this.analyser.fftSize = 2048;
          const bufferLength = _this.analyser.fftSize;
          console.log(bufferLength);
          // We can use Float32Array instead of Uint8Array if we want higher precision
          // const dataArray = new Float32Array(bufferLength);
          const dataArray = new Uint8Array(bufferLength);
          console.log(dataArray);

          const WIDTH=300;const HEIGHT=200;
          _this.waveform.clearRect(0, 0, WIDTH, HEIGHT);

          _this.audioWaveTimer = setInterval(function(){
          //const draw = () => {
            //_this.drawVisual = requestAnimationFrame(draw);
            _this.analyser.getByteTimeDomainData(dataArray);
            console.log(dataArray);

            _this.waveform.fillStyle = "rgb(200, 200, 200)";
            _this.waveform.fillRect(0, 0, WIDTH, HEIGHT);

            _this.waveform.lineWidth = 2;
            _this.waveform.strokeStyle = "rgb(0, 0, 0)";

            _this.waveform.beginPath();

            const sliceWidth = (WIDTH * 1.0) / bufferLength;
            let x = 0;

            for (let i = 0; i < bufferLength; i++) {
              const v = dataArray[i] / 128.0;
              const y = (v * HEIGHT) / 2;

              if (i === 0) {
                _this.waveform.moveTo(x, y);
              } else {
                _this.waveform.lineTo(x, y);
              }

              x += sliceWidth;
            }

            _this.waveform.lineTo(WIDTH, HEIGHT / 2);
            _this.waveform.stroke();
          }, 30);*/


        })
        .catch(function(err) { console.log(err.name + ": " + err.message); });
    }
  },
  beforeDestroy(){
    this.MediaStreamTrack && this.MediaStreamTrack.stop();
  },
  mounted() {


    const _this = this;
    this.$nextTick(()=> {
      this.playerEl = this.$refs.talkVedioEl;
      //this.waveform = this.$refs.waveform;
      this.waveform = this.$refs.waveform.getContext('2d');//document.getElementById('waveform').getContext('2d')
      const canvas = this.$refs.waveform;
      const canvasCtx = this.$refs.waveform.getContext('2d');
      // 设置画布大小与视频同样宽高
      /*
      this.waveform.canvas.width=300;
      this.waveform.canvas.height=200;
*/
      canvas.width = 300;
      canvas.height = 100;

      this.playerEl.addEventListener("loadedmetadata", function () {
        _this.playerEl.play();
        _this.audioCtx = new (window.AudioContext || window.webkitAudioContext || window.mozAudioContext)();
        // 获取音视频上下文
        _this.sourceNode = _this.audioCtx.createMediaStreamSource(_this.playerEl.srcObject);
        _this.analyser = _this.audioCtx.createAnalyser();
        _this.sourceNode.connect(_this.analyser);
        _this.analyser.connect(_this.audioCtx.destination);

        // 分配缓冲区
        _this.analyser.minDecibels = -90;
        _this.analyser.maxDecibels = -10;
        _this.analyser.smoothingTimeConstant = 0.85;
        //_this.sourceNode.connect(_this.analyser);
        _this.analyser.fftSize = 512;
        const bufferLength = _this.analyser.frequencyBinCount;
        let dataArray = new Uint8Array(bufferLength);
        console.log("bufferLength=%o",bufferLength);
        const oW = canvas.width;
        const oH = canvas.height;
        const rate = (oH/2)/255;
        console.log("rate=%o",rate);
        //根据两个给定的坐标值所构成的线段创建一个线性渐变。
        const color1 = canvasCtx.createLinearGradient(oW / 2, oH / 2 - 10, oW / 2, oH / 2 - 150);
        const color2 = canvasCtx.createLinearGradient(oW / 2, oH / 2 + 10, oW / 2, oH / 2 + 150);
        color1.addColorStop(0, '#1E90FF');
        color1.addColorStop(.25, '#FF7F50');
        color1.addColorStop(.5, '#8A2BE2');
        color1.addColorStop(.75, '#4169E1');
        color1.addColorStop(1, '#00FFFF');
        color2.addColorStop(0, '#1E90FF');
        color2.addColorStop(.25, '#FFD700');
        color2.addColorStop(.5, '#8A2BE2');
        color2.addColorStop(.75, '#4169E1');
        color2.addColorStop(1, '#FF0000');
        // 每次更新时重新计算波形值
        _this.audioWaveTimer = setInterval(function () {
          let barHeight;// 自定义获取数组里边数据的频步

          canvasCtx.clearRect(0, 0, oW, oH);
          for (let i = 0; i < bufferLength; i++) {
            barHeight = dataArray[i] * rate;
            //console.log("barHeight=%o",barHeight);
            if (barHeight === 0) barHeight = 0.5;
            _this.analyser.getByteFrequencyData(dataArray);// 绘制向上的线条
            canvasCtx.fillStyle = color1;
            /* context.fillRect(x,y,width,height)* x，y是坐标* width，height线条的宽高*/
            canvasCtx.fillRect(oW / 2 + (i * 8), oH / 2, 2, -barHeight);
            canvasCtx.fillRect(oW / 2 - (i * 8), oH / 2, 2, -barHeight);// 绘制向下的线条
            canvasCtx.fillStyle = color2;
            canvasCtx.fillRect(oW / 2 + (i * 8), oH / 2, 2, barHeight);
            canvasCtx.fillRect(oW / 2 - (i * 8), oH / 2, 2, barHeight);
          }


          /*//绘制波形图
          _this.waveform.clearRect(0, 0, _this.waveform.canvas.width, _this.waveform.canvas.height);
          console.log(">>>>>>> width:%o,height:%o,bufferLength=%o",_this.waveform.canvas.width,_this.waveform.canvas.height,_this.bufferLength);
          // 获取当前时间点的波形数组
          const dataArray = new Uint8Array(_this.bufferLength);
          _this.analyser.getByteTimeDomainData(dataArray);
          //console.log(">>>>>>> dataArray:%o",dataArray);
          // 根据波形数组绘制曲线
          for (let i = 0; i < _this.bufferLength; ++i) {
            const value = dataArray[i] / 256;
            const y = Math.floor((value * _this.waveform.canvas.height));
            if (i === 0) {
              _this.waveform.moveTo(i, y);
            } else {
              _this.waveform.lineTo(i, y);
            }
          }

          // 关闭路径并绘制曲线
          _this.waveform.strokeStyle = 'rgba(255, 0, 0, 0.7)';
          _this.waveform.lineWidth = 2;
          _this.waveform.closePath();
          _this.waveform.stroke();*/
        }, 30);
      });
    });
  }
}

</script>
<style>

</style>
